package view.mt4j.component;

import model.Statechart;
import model.util.Dimension;
import model.util.Point;

import org.mt4j.components.visibleComponents.shapes.MTRectangle;
import org.mt4j.components.visibleComponents.shapes.MTRoundRectangle;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.util.MTColor;
import org.mt4j.util.math.ToolsGeometry;
import org.mt4j.util.math.Vector3D;

import controller.ApplicationController;
import controller.view.StatechartController;
import controller.view.WorkspaceController;

import processing.core.PApplet;

import view.interfaces.statechart.StatechartView;
import view.interfaces.workspace.WorkspaceView;
import view.mt4j.workspace.WorkspaceViewImpl;
import static app.ViewConstants.*;

public class StatechartViewImpl extends MTRectangle implements StatechartView {

	private final Statechart statechart;
	private WorkspaceViewImpl workspaceView;
	private ApplicationController applicationController;
	private WorkspaceController workspaceController;
	private StatechartController statechartController;
	private MTRoundRectangle shape;

	public StatechartViewImpl(PApplet pApplet,WorkspaceViewImpl workspaceView, final Statechart statechart) {
		super(pApplet, 0, 0, 0, 0);
		this.workspaceView = workspaceView;
		this.statechart = statechart;
		this.setAnchor(PositionAnchor.UPPER_LEFT);
		drawShape();
	}

	private void drawShape() {

		shape = new MTRoundRectangle(getRenderer(), 0, 0, 0,
				DEFAULT_STATECHART_WIDTH, DEFAULT_STATECHART_HEIGHT, 7, 7);

		this.addChild(shape);
		shape.setFillColor(MTColor.WHITE);
		shape.setStrokeColor(MTColor.BLACK);
		shape.setPositionRelativeToParent(new Vector3D(
				DEFAULT_STATECHART_WIDTH / 2f, DEFAULT_STATECHART_HEIGHT / 2f)); // useless,
																					// immediately
																					// overwritten
		shape.removeAllGestureEventListeners(DragProcessor.class);
		shape.addGestureListener(DragProcessor.class, new IGestureEventListener() {
					public boolean processGestureEvent(MTGestureEvent ge) {
						DragEvent de = (DragEvent)ge;
		 
						shape.translateGlobal(de.getTranslationVect());
		 
						Vector3D[] v1 = workspaceView.getVerticesGlobal();
						Vector3D[] v2 = shape.getBounds().getVectorsGlobal();
						boolean inside = true;
						for (Vector3D vector3d : v2) {
							if (!ToolsGeometry.isPolygonContainsPoint(v1, vector3d)){
								inside = false;
							}
						}
		 
						if (!inside){
							shape.translateGlobal(de.getTranslationVect().getScaled(-1));
						}
						return false;
					}
				});
	}

	@Override
	public void setController(ApplicationController applicationController,
			WorkspaceController workspaceController,
			StatechartController statechartController) {
		this.applicationController = applicationController;
		this.workspaceController = workspaceController;
		this.statechartController = statechartController;
	}

	@Override
	public Statechart getStatechart() {
		return statechart;
	}

	@Override
	public Dimension getSize() {
		Dimension dim = workspaceController.getWorkspace()
				.getStatechartDimension(statechart.getId());
		if (dim != null) {
			return dim;
		}
		return new Dimension(DEFAULT_STATECHART_WIDTH,
				DEFAULT_STATECHART_HEIGHT);
	}

	@Override
	public void setSize(Dimension size) {
		shape.setSizeLocal(size.width, size.height);
		// workspaceController.getWorkspace().setStatechartDimension(statechart.getId(),
		// size);
	}

	@Override
	public Point getLocation() {
		return workspaceController.getWorkspace().getStatechartLocation(
				statechart.getId());
	}

	@Override
	public void setLocation(Point point) {
		this.setPositionRelativeToParent(new Vector3D(point.x - getSize().width
				/ 2f, point.y - getSize().height / 2f));
		// workspaceController.getWorkspace().setStatechartLocation(statechart.getId(),
		// point);
	}

	@Override
	public void select() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void unselect() {
		// TODO Auto-generated method stub
		
	}

}
